# 视频根据字幕的内容进行自动剪辑的处理类
import json
import os
import glob
import pubfunc
import shutil
import dbClipExecute
# 根据subtitle.srt的内容，来生成视频的截取方案
class ClipClass():
    # video是视频的地址，subdata是字幕的内容，flag是压制字幕，如果1：则压制字幕，0:不压制
    def __init__(self, video, uuid1, tmd5, subdata, brate):
        self.uuid1 = uuid1
        self.tmd5 = tmd5
        self.brate = brate
        # 根据resolution进行宽高的提取
        self.wpath = f"./tmp/{pubfunc.getsUUID()}"
        self.spath = f"{self.wpath}/segments"
        self.subdata = subdata
        self.video = video

    # 压制字幕
    def supSubtitles(self):
        # 根据subdata的内容，生成字幕文件， 字幕文件中去掉sflag==1的内容；
        subfile = f"{self.wpath}/subtitle.vtt"
        array = []
        # for sub in self.subdata:
        #     flag = sub["sflag"]
        #     # if(flag == 1):
        #     array.append(sub)
                
        pubfunc.jsonToVtt(self.subdata, subfile)
        target = f"{self.wpath}/starget.mp4"
        # pubfunc.videoAddSubtitle(self.video, subfile, target)
        pubfunc.tr1080pAddSubtitle(self.video, subfile, target)
        self.video = target

    # 进行字幕的切片进行处理
    def mkVideoResult(self):
        # 首先需要建立工作目录(会重新建立,如果目录存在，则清空)
        pubfunc.reMkDir(self.spath)
        # 根据字幕的屏蔽(切割）信息，生成切割内容；(每部分内容保留时间戳)
        # subtitle中的两个标志来判断是否进行切割 subtitle1["flag"] = 1, 如果flag=0,则不需要该内容
        arry = []
        pindex = 0
        stime = 0
        etime = 0
        
        dbClipExecute.addClipTaskLog(self.uuid1, "开始分析字幕切片的内容")

        # 根据index的顺序，来确定是否需要生成内容；
        for index, sub in enumerate(self.subdata):
            # 把相近的内容，如果sflag一致，则合并到一个时间段内
            start = sub["start"]
            end = sub["end"]
            sflag = sub["sflag"]
            if(index != 0 and etime == 0 and sflag == 1):
                stime = start
            if sflag == 1:
                etime = end
                continue
            if(sflag != 1 and etime != 0):
                pp = {}
                pp["start"] = stime
                pp["end"] = etime
                arry.append(pp)
                stime = 0
                etime = 0

        if(etime != 0):
            pp = {}
            pp["start"] = stime
            pp["end"] = etime
            arry.append(pp)
        
        dbClipExecute.addClipTaskLog(self.uuid1, "开始进行视频切片处理")

        for index, sub in enumerate(arry):
            start = sub["start"]
            end = sub["end"]
            sfile = f"{self.spath}/{index:07}.mp4"
            pubfunc.clipperVideo(self.video, sfile, start, end)
        # 根据分割的内容，生成最终的结果
        dbClipExecute.addClipTaskLog(self.uuid1, "内容合成打包")
        rpath =f"{self.wpath}/result"
        pubfunc.reMkDir(rpath)
        # 读取当前目录，并合并到一个视频文件中
        farray = []
        for f in sorted(glob.glob(f"{self.spath}/*.mp4")):
            fname = os.path.basename(f)
            farray.append(fname)
        
        # 为了保证最后时间音频的正常，把最后一帧多增加2帧
        pubfunc.addEndFrame(f"{self.spath}/{farray[-1]}")
        target = f"{rpath}/result.mp4"
        self.mergeSegment(farray, target)
        # 把当前的字幕也一并打包，给返回；
        subtxt = f"{rpath}/subtitle.json"
        with open(subtxt, 'w+', encoding='utf-8') as f:
            # 使用 json.dump 将 JSON 数组写入文件
            json.dump(self.subdata, f, ensure_ascii=False, indent=4)
        zipfile = f"{self.wpath}/{self.uuid1}.zip"
        pubfunc.mkZip(zipfile, rpath)
        # 把生成的zip文件迁移到文件目录中
        toPath = f"{os.environ.get('SUBTASK_PATH')}/{self.tmd5}/"
        url = f"{os.environ.get('SUBTASK_URL')}/{self.tmd5}/{self.uuid1}.zip"
        pubfunc.havePath(toPath)
        shutil.move(zipfile, toPath)
        # 合成后生成截图与时长的提取和生成
        thumbnail = f"{self.wpath}/thumbnail.png"
        pubfunc.videoShot(target, thumbnail)
        tfilename = f"{pubfunc.getsUUID()}.png"
        tfile = f"{os.environ.get('SUBTASK_PATH')}/{self.tmd5}/{tfilename}"
        tfileurl = f"{os.environ.get('SUBTASK_URL')}/{self.tmd5}/{tfilename}"
        duration, _ = pubfunc.getDurationAndResolution(target)
        shutil.move(thumbnail, tfile)
        dbClipExecute.updateClipSubOutUrl(self.uuid1, url)
        dbClipExecute.updateClipSubThumbnailDuration(self.uuid1, tfileurl, duration)
        return toPath, url
    
    def mergeSegment(self, farray, target):
        # 根据farray的内容，生成concat.lst的内容
        concat = f"{self.spath}/concat.lst"
        with open(concat, "w+") as f:
            for file in farray:
                f.write(f"file {file}\n")
        pubfunc.concatVideo(concat, target)

    # # 根据策略来分割视频
    # def mkResultVideo(filelist):
    #     result = f"{os.path.dirname(filelist)}/result.mp4"
    #     pubfunc.concatVideo(filelist, result)

    def execute(self):
        try: 
            pubfunc.reMkDir(self.wpath)

            nvideo = f"{self.wpath}/video.mp4"
            pubfunc.download(self.video, nvideo)
            self.video = nvideo
            # 根据字幕内容生面最后视频内容
            return self.mkVideoResult()
        except Exception as e:
            print(str(e))
            return None, '剪切处理错误!' 
        # 把临时的目录删除
        finally:
            shutil.rmtree(self.wpath)

        
        # 把相应的片段内容，迁移到最终目录，并写入数据库

# 根据narry来生成最终的内容, 因为narry中的seq如果为连续，则是需要保留的内容，如果不连续，则是需要删除的内容
if __name__ == "__main__" :  
    pass

